這裡放了一個名字叫 customCanvas 的 View 在畫面上,我們打算在這個 View 的 Layer 上畫圖。
這裡通過 UIBezierPath 來畫出上面這張圖,當然靠想像力來畫有點難度,可以借助 PaintCode 這樣的工具來幫忙。
private var customPath: UIBezierPath {
let bezier2Path = UIBezierPath()
bezier2Path.move(to: CGPoint(x: 166.1, y: 48.28))
bezier2Path.addCurve(to: CGPoint(x: 166.1, y: 131.72), controlPoint1: CGPoint(x: 199.3, y: 71.32), controlPoint2: CGPoint(x: 199.3, y: 108.68))
bezier2Path.addCurve(to: CGPoint(x: 89.68, y: 147.91), controlPoint1: CGPoint(x: 145.34, y: 146.13), controlPoint2: CGPoint(x: 116.5, y: 151.53))
bezier2Path.addCurve(to: CGPoint(x: 43.5, y: 169.5), controlPoint1: CGPoint(x: 71.56, y: 159.66), controlPoint2: CGPoint(x: 43.5, y: 169.5))
bezier2Path.addCurve(to: CGPoint(x: 58.33, y: 138.86), controlPoint1: CGPoint(x: 43.5, y: 169.5), controlPoint2: CGPoint(x: 53.16, y: 153.11))
bezier2Path.addCurve(to: CGPoint(x: 45.9, y: 131.72), controlPoint1: CGPoint(x: 53.95, y: 136.8), controlPoint2: CGPoint(x: 49.78, y: 134.42))
bezier2Path.addCurve(to: CGPoint(x: 45.9, y: 48.28), controlPoint1: CGPoint(x: 12.7, y: 108.68), controlPoint2: CGPoint(x: 12.7, y: 71.32))
bezier2Path.addCurve(to: CGPoint(x: 166.1, y: 48.28), controlPoint1: CGPoint(x: 79.09, y: 25.24), controlPoint2: CGPoint(x: 132.91, y: 25.24))
bezier2Path.close()
bezier2Path.lineWidth = 9
bezier2Path.stroke()
return bezier2Path
}
然後定義 shapeLayer:CAShapeLayer 的基本參數,比如粗細、顏色、填充等等,其中 path 就是上圖的路徑。
lazy var shapeLayer:CAShapeLayer = {
let layer = CAShapeLayer()
layer.path = customPath.cgPath
layer.strokeColor = UIColor.yellow.cgColor
layer.fillColor = UIColor.clear.cgColor
layer.lineWidth = 4.0
layer.lineCap = kCALineCapRound
return layer
}()
並將它加入到 customCanvas 當中
customCanvas.layer.addSublayer(shapeLayer)
當我們拖動 UiSlider 的時候,改變畫圖的進度
shapeLayer.strokeEnd = CGFloat(slider.value)
我們另外建了一個 LoadingViewController 用來顯示 Loading 的畫面。
這次要畫的圓的路徑就容易多了
private var customPath: UIBezierPath {
let bezierPath = UIBezierPath(ovalIn: CGRect(x: 35, y: 35, width: 75, height: 75))
return bezierPath
}
然後在加入到 shapeLayer 當中
lazy var shapeLayer:CAShapeLayer = {
let layer = CAShapeLayer()
layer.path = customPath.cgPath
layer.strokeColor = UIColor.blue.cgColor
layer.fillColor = UIColor.clear.cgColor
layer.lineWidth = 4.0
layer.lineCap = kCALineCapRound
return layer
}()
這次多了自動去執行動畫的部分,通過 repeatCount 可以設定動畫執行的次數,這裡設定了無數次 Float.infinity
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = 0.0
animation.byValue = 1.0
animation.duration = 1.5
animation.fillMode = kCAFillModeForwards
animation.isRemovedOnCompletion = false
animation.repeatCount = Float.infinity
shapeLayer.add(animation, forKey: "drawChatIconAnimation")
這裡把 ViewController 最底層的 View 設定了 backGroundColor = UIColor.clear
這樣搭配設定 modalPresentationStyle / modalTransitionStyle 可以實現 ViewController 半透明的效果。
在 HomeViewController 中, present LoadingViewController
let VC = LoadingViewController()
VC.modalPresentationStyle = .overFullScreen
VC.modalTransitionStyle = .crossDissolve
present(VC, animated: true, completion: nil)
思考:在使用 UIBezierPath 畫圖的時候,如何實現 autoLayout 而不是 hard code 方式給予數字。